package common;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;

import modules.configuration.GameConf;
import modules.gameCommunication.GameServerThread;
import modules.intercommunication.InterServerThread;
import modules.intercommunication.InterServerThreadFactory;

public class GameServer {

    private static InterServerThread _IST;
    private static byte _state = Constants.SERVER_STATE_OFFLINE;
    private static GameServerThread _GST;

    public static void main(String[] args) {
        String file = "game.conf";
        if (args.length > 0) {
            file = args[0];
        }

        GameConf.loadConfigFile(file);

        writeLine("Ancestra 1.0 Game Server");
        writeLine("By Mellancholia & Diabu for Dofus 1.29.1");
        writeLine("==============================================================");
        writeLine("&Loading configuration: ");
        writeLine("Ok!");
        if (GameConf._debug) {
            writeLine("Debug mode on !");
        }
        writeLine("Game Server Id : " + GameConf._gameServerId);
        writeLine("&Database Connection Test... ");
        //Initialize the SQLManager with 10 threads
        new SQLMgr((byte) 10);

        //If test fails
        if (!SQLMgr.onInitTest()) {
            writeLine("");
            writeLine("Error while testing the Database Connexion, please verify your configuration");
            return;
        }

        if (!SQLMgr.setSQLConnection()) {
            writeLine("");
            writeLine("Error : unable connect to the DataBase");
        }
        writeLine("Ok!");

        writeLine("&Loading experience table : ");
        LoadingData.loadExp();

        writeLine("&Loading races datas : ");
        LoadingData.loadRaces();

        writeLine("&Loading maps datas : ");
        LoadingData.loadMaps();

        writeLine("&Loading map triggers : ");
        LoadingData.loadMapTriggers();

        writeLine("&Loading items : ");
        LoadingData.loadItems();
        
        writeLine("&Loading monsters : ");
        LoadingData.loadMonsters();
        
        writeLine("&Loading groups monster : ");
        LoadingData.loadMapMonsterGroups();

        writeLine("&Loading subareas : ");
        LoadingData.loadSubAreas();
        
        writeLine("&Loading spells : ");
        LoadingData.loadSpells();
        
        writeLine("&Launching inter-server socket on port " + GameConf._interPort + "... ");
        new InterServerThreadFactory();

        try {
            Thread.sleep(500);
        } catch (Exception E) {
        };

        writeLine("&Launching game-server socket on port " + GameConf._gamePort + "... ");
        _GST = new GameServerThread();
    }

    /**
     * Update state to the Realmserver if possible
     * @param state
     */
    public static void updateState(byte state) {
        _state = state;
        if (_IST == null) {
            return;
        }
        _IST.sendPacket(PacketFormatter.getISUpdateStatePacket(_state));
    }

    /**
     * Write a line into log File & Console
     * @param line : The line to write on Console & Logs
     */
    public static void writeLine(String line) {
        if (line.charAt(0) == '&') {
            line = line.substring(1);
            System.out.print(line);

        } else {
            System.out.println(line);
        }
        if (!GameConf._log) {
            return;
        }
        String time = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) + ":" + Calendar.getInstance().get(+Calendar.MINUTE) + ":" + Calendar.getInstance().get(Calendar.SECOND);
        String date = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "_" + Calendar.getInstance().get(Calendar.MONTH) + "_" + Calendar.getInstance().get(Calendar.YEAR);
        BufferedWriter log;
        try {
            File f = new File("./Game_Logs/");
            //If Directory does not exist, create the Directory
            if (!f.exists()) {
                f.mkdir();
            }
            log = new BufferedWriter(new FileWriter("./Game_Logs/" + date + ".txt"));
            log.write(time + " > " + line + "\r\n");
            log.flush();
            log.close();
        } catch (IOException e) {
            System.out.println("Warning: Log file cannot be opened, logs are now desactivate.");
            GameConf._log = false;
        }
    }

    public static byte getState() {
        return _state;
    }

    public static void setInterServerThread(InterServerThread ist) {
        _IST = ist;
    }

    public static void closeServer(long s) {
        try {
            Thread.sleep(s);
        } catch (Exception e) {
        };
        _IST.stop();
        _GST.stop();
        System.exit(0);
    }
}
